<html>
<head><meta charset="utf-8"><title>subobligations and ICEs #85868 · wg-traits · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/index.html">wg-traits</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html">subobligations and ICEs #85868</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="244163692"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244163692" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244163692">(Jun 28 2021 at 15:39)</a>:</h4>
<p>Hey <span class="user-mention" data-user-id="125294">@Aaron Hill</span></p>



<a name="244176894"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244176894" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244176894">(Jun 28 2021 at 17:17)</a>:</h4>
<p>The fact that we can't easily ignore <code>Sized</code> predicates really limits our options</p>



<a name="244316930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244316930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244316930">(Jun 29 2021 at 17:24)</a>:</h4>
<p>I'm starting to wonder if we can avoid <code>EvaluatedToOkModuloRegions</code> when we start out with a global predicate</p>



<a name="244317029"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244317029" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244317029">(Jun 29 2021 at 17:25)</a>:</h4>
<p>If we encounter higher-ranked bounds deeper into evaluation, they'll need to take on a restricted form, since we didn't start out with any input regions (other that <code>'static</code>)</p>



<a name="244317480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244317480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244317480">(Jun 29 2021 at 17:28)</a>:</h4>
<p>E.g. we can have <code>for&lt;'a&gt; SomeType&lt;'a, 'static&gt;: SomeTrait&lt;'a, 'static&gt;</code></p>



<a name="244317529"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244317529" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244317529">(Jun 29 2021 at 17:28)</a>:</h4>
<p>But the nested predicate can't reference any other regions, since we didn't have any others to start with</p>



<a name="244321694"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244321694" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244321694">(Jun 29 2021 at 17:59)</a>:</h4>
<p>So, I wonder if we can do some kind of simplified evaluation that lets us get either EvalatuedToOk or EvaluatedToErr,</p>



<a name="244321747"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244321747" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244321747">(Jun 29 2021 at 17:59)</a>:</h4>
<p>which would let us drop global predicates from the predicate sub-obligation</p>



<a name="244340395"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244340395" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244340395">(Jun 29 2021 at 20:11)</a>:</h4>
<p>I'm reluctant to do that, I think</p>



<a name="244340447"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244340447" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244340447">(Jun 29 2021 at 20:11)</a>:</h4>
<p>Let me think why =)</p>



<a name="244340522"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244340522" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244340522">(Jun 29 2021 at 20:12)</a>:</h4>
<p>I think what worries me is that the current logic for "higher-ranked regions" is not as smart as I would like</p>



<a name="244340542"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244340542" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244340542">(Jun 29 2021 at 20:12)</a>:</h4>
<p>we worked hard to get rid of the leak check etc in most cases</p>



<a name="244340604"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244340604" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244340604">(Jun 29 2021 at 20:12)</a>:</h4>
<p>and i'm worried that if we return <code>EvaluatedToErr</code> some parts of the code will start to accept impls or otherwise do things that will be accepting code we might not want to ultimately accept (this is already a problem; I'm worried about making it worse)</p>



<a name="244367613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244367613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244367613">(Jun 30 2021 at 01:14)</a>:</h4>
<p>I see</p>



<a name="244367624"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244367624" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244367624">(Jun 30 2021 at 01:14)</a>:</h4>
<p>In that case, I think we're pretty much stuck returning the full set of sub-obligations from the projection cache</p>



<a name="244367637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244367637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244367637">(Jun 30 2021 at 01:15)</a>:</h4>
<p>since we cannot avoid <code>EvaluatedToOkModuloRegions</code>, and we cannot detect it in advance</p>



<a name="244367956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244367956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244367956">(Jun 30 2021 at 01:20)</a>:</h4>
<p>Here's an alternative idea - all of the sub-obligations we create (in the <code>deeply-nested</code> benchmark) will end up getting registered with the <code>FulfillmentContext</code></p>



<a name="244367973"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244367973" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244367973">(Jun 30 2021 at 01:20)</a>:</h4>
<p>so, we end up calling <code>SelectionContext.select</code> on the same predicate many different times</p>



<a name="244368058"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244368058" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244368058">(Jun 30 2021 at 01:22)</a>:</h4>
<p>We have a selection candidate cache - would it make sense to try to introduce a 'selection result' cache?</p>



<a name="244368157"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244368157" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244368157">(Jun 30 2021 at 01:24)</a>:</h4>
<p>we would need to adjust the <code>ObligationCause</code> to combined the cached cause with the cause of the new obligation</p>



<a name="244966911"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244966911" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244966911">(Jul 05 2021 at 19:19)</a>:</h4>
<p>I've tried a different approach in PR <a href="https://github.com/rust-lang/rust/pull/86871">https://github.com/rust-lang/rust/pull/86871</a> . Whenever we have any sub-obligations, we add a dummy sub-obligation that forces the result to <code>EvaluatedToOkModuloRegions</code></p>



<a name="244989027"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/244989027" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#244989027">(Jul 06 2021 at 02:16)</a>:</h4>
<p>Yet another approach is  <a href="https://github.com/rust-lang/rust/pull/86896">https://github.com/rust-lang/rust/pull/86896</a> - we normally use the pruned obligations, but switch to using the original full list of obligations during trait obligation. It's a more complex change, but the performance is better, and it still fixes the fingerprint issue</p>



<a name="245050811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/245050811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nikomatsakis <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#245050811">(Jul 06 2021 at 14:59)</a>:</h4>
<p>ok, let me compare</p>



<a name="245066992"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/245066992" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#245066992">(Jul 06 2021 at 16:51)</a>:</h4>
<p>To summarize, the three approaches I've come up with are:</p>
<ol>
<li>Always return the original full list of sub-obligations from the projection cache. This is clearly sound, but leads to large regressions on some benchmarks. It fixes the fingerprint ICE by ensuring that evaluation will consistently produce EvaluatedToOk(ModuloRegions) regardless of the state of the projection cache.</li>
<li>Add a dummy sub-obligation if we have any sub-obligation to begin with, forcing the evaluation result to EvaluatedToOkModuloRegions. This is also sound, since it's always correct to replace EvaluatedToOk with EvaluatedToOkModuloRegions. It fixes the fingerprint ICE by always producing EvaluatedToOkModuloRegions, so it doesn't matter what particular result is produced by our pruned sub-obligation in the projection cache.</li>
<li>Use the full-set of sub-obligation during trait evaluation, and the pruned set otherwise. This should be sound, but I'm not 100% certain. It fixes the ICE by ensuring that the evaluation query doesn't depend on the state of the projection cache.</li>
</ol>



<a name="245067233"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/144729-wg-traits/topic/subobligations%20and%20ICEs%20%2385868/near/245067233" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Aaron Hill <a href="https://rust-lang.github.io/zulip_archive/stream/144729-wg-traits/topic/subobligations.20and.20ICEs.20.2385868.html#245067233">(Jul 06 2021 at 16:53)</a>:</h4>
<p>I think there's going to be at least a moderate performance hit no matter what we do</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>